package com.example.dianproject.service.impl;

import com.example.dianproject.dto.MeterDTO;
import com.example.dianproject.entity.Customer;
import com.example.dianproject.entity.Meter;
import com.example.dianproject.repository.CustomerRepository;
import com.example.dianproject.repository.MeterRepository;
import com.example.dianproject.service.MeterService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityNotFoundException;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class MeterServiceImpl implements MeterService {

    @Autowired
    private MeterRepository meterRepository;

    @Autowired
    private CustomerRepository customerRepository;

    @Override
    @Transactional(readOnly = true)
    public List<MeterDTO> getAllMeters() {
        return meterRepository.findAllWithCustomer().stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    @Override
    @Transactional(readOnly = true)
    public List<Meter> getAllMetersWithDetails() {
        return meterRepository.findAllWithCustomer();
    }

    @Override
    @Transactional(readOnly = true)
    public MeterDTO getMeterById(Long meterId) {
        return meterRepository.findByIdWithCustomer(meterId)
                .map(this::convertToDTO)
                .orElseThrow(() -> new EntityNotFoundException("电表不存在"));
    }

    @Override
    @Transactional
    public MeterDTO createMeter(MeterDTO meterDTO) {
        // 验证电表编号是否已存在
        if (meterRepository.existsByMeterCode(meterDTO.getMeterCode())) {
            throw new IllegalArgumentException("电表编号已存在");
        }

        Meter meter = convertToEntity(meterDTO);
        meter = meterRepository.save(meter);
        return convertToDTO(meter);
    }

    @Override
    @Transactional
    public MeterDTO updateMeter(Long meterId, MeterDTO meterDTO) {
        // 验证电表编号是否已被其他电表使用
        if (meterRepository.existsByMeterCodeAndMeterIdNot(meterDTO.getMeterCode(), meterId)) {
            throw new IllegalArgumentException("电表编号已存在");
        }

        Meter meter = meterRepository.findById(meterId)
                .orElseThrow(() -> new EntityNotFoundException("电表不存在"));

        updateMeterFromDTO(meter, meterDTO);
        meter = meterRepository.save(meter);
        return convertToDTO(meter);
    }

    @Override
    @Transactional
    public void deleteMeter(Long meterId) {
        if (!meterRepository.existsById(meterId)) {
            throw new EntityNotFoundException("电表不存在");
        }
        meterRepository.deleteById(meterId);
    }

    @Override
    @Transactional(readOnly = true)
    public long getMeterCount() {
        return meterRepository.count();
    }

    private MeterDTO convertToDTO(Meter meter) {
        MeterDTO dto = new MeterDTO();
        dto.setMeterId(meter.getMeterId());
        dto.setMeterCode(meter.getMeterCode());
        dto.setInstallationDate(meter.getInstallationDate());
        dto.setMultiplier(meter.getMultiplier());
        dto.setCurrentReading(meter.getCurrentReading());

        if (meter.getCustomer() != null) {
            dto.setCustomerId(meter.getCustomer().getCustomerId());
            dto.setCustomerName(meter.getCustomer().getCustomerName());
            dto.setCustomerCode(meter.getCustomer().getCustomerCode());
        }

        return dto;
    }

    private Meter convertToEntity(MeterDTO dto) {
        Meter meter = new Meter();
        meter.setMeterId(dto.getMeterId());
        meter.setMeterCode(dto.getMeterCode());
        meter.setInstallationDate(dto.getInstallationDate());
        meter.setMultiplier(dto.getMultiplier());
        meter.setCurrentReading(dto.getCurrentReading());

        if (dto.getCustomerId() != null) {
            Customer customer = customerRepository.findById(dto.getCustomerId())
                    .orElseThrow(() -> new EntityNotFoundException("客户不存在"));
            meter.setCustomer(customer);
        }

        return meter;
    }

    private void updateMeterFromDTO(Meter meter, MeterDTO dto) {
        meter.setMeterCode(dto.getMeterCode());
        meter.setInstallationDate(dto.getInstallationDate());
        meter.setMultiplier(dto.getMultiplier());
        meter.setCurrentReading(dto.getCurrentReading());

        if (dto.getCustomerId() != null) {
            Customer customer = customerRepository.findById(dto.getCustomerId())
                    .orElseThrow(() -> new EntityNotFoundException("客户不存在"));
            meter.setCustomer(customer);
        }
    }
} 